# -*- coding: utf-8 -*-
# @Time: 2023/4/20 16:07
# @File: views.py
# @Desc:CMS管理后台视图函数

from flask import Blueprint
from utils import restful
from flask_jwt_extended import jwt_required, get_jwt_identity
from .froms import UploadBannerForm, AddBannerForm, EditBannerForm
from flask import request, g, current_app
import os
from hashlib import md5
import time
from models.auth import User, Permission
from models.common import Banner, Post, Comment, Board
from exts import db
from sqlalchemy import func
from datetime import datetime, timedelta
from .decrorators import permission_required

bp_csm = Blueprint("cmsapi", __name__, url_prefix="/cmsapi")


# 钩子函数
@bp_csm.before_request
@jwt_required()
def before_request():
    if request.method == "OPTIONS":
        return
    identity = get_jwt_identity()
    user = User.query.filter_by(id=identity).first()
    if user:
        setattr(g, "user", user)


# 测试
@bp_csm.get("/")
@jwt_required()
def test():
    return restful.success(message="test successful")


# 轮播图上传
@bp_csm.post("/banner/images/upload/")
@permission_required(Permission.BANNERS)
def upload_banner_images():
    form = UploadBannerForm(request.files)
    if form.validate():
        image = form.image.data
        filename = image.filename
        _, ext = os.path.splitext(filename)
        filename = md5((g.user.id + str(time.time())).encode("utf8")).hexdigest() + ext
        image_path = os.path.join(current_app.config["BANNER_IMAGE_SAVE_PATH"], filename)
        image.save(image_path)
        return restful.success(data={'image': filename})
    else:
        return restful.params_error(message=form.messages[0])


# 添加轮播图
@bp_csm.post("/banner/add/")
@permission_required(Permission.BANNERS)
def add_banner():
    form = AddBannerForm(request.form)
    if form.validate():
        name = form.name.data
        img_url = form.img_url.data
        url_to = form.url_to.data
        priority = form.priority.data
        banner = Banner(name=name, img_url=img_url, url_to=url_to, priority=priority)
        db.session.add(banner)
        db.session.commit()
        return restful.success(data=banner.to_dict())
    else:
        return restful.params_error(message=form.messages[0])


# 轮播图列表
@bp_csm.get("/banner/list/")
@permission_required(Permission.BANNERS)
def banner_list():
    banners = Banner.query.order_by(Banner.create_date.desc()).all()
    banner_dicts = [banner.to_dict() for banner in banners]
    return restful.success(data=banner_dicts)


# 删除轮播图
@bp_csm.post("/banner/delete/")
@permission_required(Permission.BANNERS)
def banner_delete():
    bid = request.form.get("id")
    if not bid:
        return restful.params_error(message="请选择轮播图进行删除操作！")
    try:
        banner = Banner.query.get(bid)
    except Exception as e:
        return restful.params_error(message="轮播图不存在，请稍后再试！")
    db.session.delete(banner)
    db.session.commit()
    return restful.success()


# 编辑轮播图
@bp_csm.post("/banner/edit/")
@permission_required(Permission.BANNERS)
def banner_edit():
    form = EditBannerForm(request.form)
    if form.validate():
        banner_id = form.id.data
        try:
            banner = Banner.query.get(banner_id)
        except Exception as e:
            return restful.params_error(message="轮播图不存在")
        name = form.name.data
        img_url = form.img_url.data
        url_to = form.url_to.data
        priority = form.priority.data
        banner.name = name
        banner.img_url = img_url
        banner.url_to = url_to
        banner.priority = priority
        db.session.commit()
        return restful.success(data=banner.to_dict())
    else:
        return restful.params_error(message=form.message[0])


# cms帖子列表
@bp_csm.get("/post/list/")
@permission_required(Permission.POSTERS)
def post_list():
    page = request.args.get("page", default=1, type=int)
    per_page_count = current_app.config["PER_PAGE_COUNT"]
    start = (page - 1) * per_page_count
    end = start + per_page_count
    post_obj = Post.query.order_by(Post.create_date.desc())
    total_count = post_obj.count()
    posts = post_obj.slice(start, end)
    post_list = [post.to_dict() for post in posts]
    data = {'total_count': total_count, "page": page, "post_list": post_list}
    return restful.success(data=data)


# 删除帖子
@bp_csm.post("/post/delete/")
@permission_required(Permission.POSTERS)
def post_delete():
    post_id = request.form.get("id")
    if not post_id:
        return restful.params_error(message="选择帖子进行删除")
    try:
        post = Post.query.get(post_id)
    except Exception as e:
        return restful.params_error(message="帖子不存在")
    db.session.delete(post)
    db.session.commit()
    return restful.success()


# 评论列表
@bp_csm.get("/comment/list/")
@permission_required(Permission.COMMETNERS)
def comments_list():
    page = request.args.get("page", default=1, type=int)
    per_page_count = current_app.config["PER_PAGE_COUNT"]
    start = (page - 1) * per_page_count
    end = start + per_page_count
    comments_obj = Comment.query.order_by(Comment.create_date.desc())
    total_count = comments_obj.count()
    comments = comments_obj.slice(start, end)
    comment_list = [comment.to_dict() for comment in comments]
    data = {'total_count': total_count, "page": page, "comment_list": comment_list}
    return restful.success(data=data)


# 删除评论
@bp_csm.post("/comment/delete/")
@permission_required(Permission.COMMETNERS)
def comment_delete():
    comment_id = request.form.get("id")
    if not comment_id:
        return restful.params_error(message="请选择评论进行删除")
    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        return restful.params_error(message="评论不存在")
    db.session.delete(comment)
    db.session.commit()
    return restful.success()


# 用户列表
@bp_csm.get("/user/list/")
@permission_required(Permission.USERS)
def user_list():
    page = request.args.get("page", default=1, type=int)
    per_page_count = current_app.config["PER_PAGE_COUNT"]
    start = (page - 1) * per_page_count
    end = start + per_page_count
    user_obj = User.query.order_by(User.join_date.desc())
    total_count = user_obj.count()
    users = user_obj.slice(start, end)
    user_list = [user.to_dict() for user in users]
    data = {'total_count': total_count, "page": page, "user_list": user_list}
    return restful.success(data=data)


# 修改用户状态
@bp_csm.post("/user/active/")
@permission_required(Permission.USERS)
def user_active():
    user_id = request.form.get("id")
    is_active = request.form.get("is_active", type=int)
    if not user_id:
        return restful.params_error(message="非法操作！")
    try:
        user = User.query.get(user_id)
    except Exception as e:
        return restful.params_error(message="用户不存在")
    user.is_active = bool(is_active)
    db.session.commit()
    return restful.success(data=user.to_dict())


# 设置用户员工状态
@bp_csm.post("/user/staff/")
@permission_required(Permission.USERS)
def user_staff():
    user_id = request.form.get("id")
    is_staff = request.form.get("is_staff", type=int)
    if not user_id:
        return restful.params_error(message="非法操作！")
    try:
        user = User.query.get(user_id)
    except Exception as e:
        return restful.params_error(message="用户不存在")
    user.is_staff = bool(is_staff)
    db.session.commit()
    return restful.success(data=user.to_dict())


# 删除用户
@bp_csm.post("/user/delete/")
@permission_required(Permission.USERS)
def user_delete():
    user_id = request.form.get("id")
    if not user_id:
        return restful.params_error(message="操作有误，请选择用户进行删除操作")
    try:
        user = User.query.get(user_id)
    except Exception as e:
        return restful.params_error(message="用户不存在")
    db.session.delete(user)
    db.session.commit()
    return restful.success()


# 根据板块获取帖子数量
@bp_csm.get("/board/post/count/")
def get_post_count_from_board():
    board_post_count_list = db.session.query(Board.name, func.count(Board.name)).join(Post).group_by(Board.name).all()
    board_names = []
    post_count = []
    for x in board_post_count_list:
        board_names.append(x[0])
        post_count.append(x[1])
    data = {"board_names": board_names, "post_count": post_count}
    return restful.success(data=data)


# 获取近期帖子数量
@bp_csm.get("/latest/post/count/")
def get_latest_post_count():
    now = datetime.now()
    # latest_date最近7天
    latest_date = now - timedelta(days=6, hours=now.hour, minutes=now.minute, seconds=now.second,
                                  microseconds=now.microsecond)
    par = func.date_format(Post.create_date, "%Y-%m-%d")
    # 获取近七天内帖子数量
    latest_post_count_list = db.session.query(par, func.count(Post.id)).group_by(par).filter(
        Post.create_date >= latest_date).all()
    latest_post_count_dict = dict(latest_post_count_list)  # 转化成字典
    for i in range(7):
        date = latest_date + timedelta(days=i)
        date_str = date.strftime("%Y-%m-%d")
        # 如果近七天内没有帖子，则对帖子数量进行0填充
        if date_str not in latest_post_count_dict:
            latest_post_count_dict[date_str] = 0
    latest_dates = sorted(list(latest_post_count_dict.keys()))  # 按日期进行排序
    post_count = []
    for date in latest_dates:
        post_count.append(latest_post_count_dict[date])  # 将帖子数量填充到列表
    result = {"latest_dates": latest_dates, "post_count": post_count}
    return restful.success(data=result)
